package zpp_nape.util;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if flash10 import flash.Memory;
import flash.utils.ByteArray;
#end#if swc@:keep#end class ZPP_Math{
    #if flash10 static function __init__(){
        var b=new ByteArray();
        b.length=1024;
        Memory.select(b);
    }
    #end public static inline function sqrt(x:Float){
        {
            #if NAPE_ASSERT var res={
                !({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
                    ret;
                    #else Math.isNaN(x);
                    #end
                });
            };
            if(!res)throw "assert("+"!assert_isNaN(x)"+") :: "+("PR(Math).sqrt");
            #end
        };
        #if flash10 return if(x==0.0)0.0 else 1/invsqrt(x);
        #else return Math.sqrt(x);
        #end
    }
    public static inline function invsqrt(x:Float){
        {
            #if NAPE_ASSERT var res={
                !({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
                    ret;
                    #else Math.isNaN(x);
                    #end
                })&&x!=0.0;
            };
            if(!res)throw "assert("+"!assert_isNaN(x)&&x!=0.0"+") :: "+("PR(Math).invsqrt");
            #end
        };
        #if flash10 Memory.setFloat(0,x);
        Memory.setI32(0,0x5f3759df-(Memory.getI32(0)>>1));
        var x2=Memory.getFloat(0);
        return x2*(1.5-0.5*x*x2*x2);
        #else return 1.0/sqrt(x);
        #end
    }
    public static inline function sqr(x:Float){
        {
            #if NAPE_ASSERT var res={
                !({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
                    ret;
                    #else Math.isNaN(x);
                    #end
                });
            };
            if(!res)throw "assert("+"!assert_isNaN(x)"+") :: "+("PR(Math).sqr");
            #end
        };
        return x*x;
    }
    public static inline function clamp2(x:Float,a:Float){
        {
            #if NAPE_ASSERT var res={
                !({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
                    ret;
                    #else Math.isNaN(x);
                    #end
                })&&!({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](a);
                    ret;
                    #else Math.isNaN(a);
                    #end
                });
            };
            if(!res)throw "assert("+"!assert_isNaN(x)&&!assert_isNaN(a)"+") :: "+("PR(Math).clamp2 -> "+x+" -> "+a);
            #end
        };
        return clamp(x,-a,a);
    }
    public static inline function clamp(x:Float,a:Float,b:Float){
        {
            #if NAPE_ASSERT var res={
                !({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](x);
                    ret;
                    #else Math.isNaN(x);
                    #end
                })&&!({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](a);
                    ret;
                    #else Math.isNaN(a);
                    #end
                })&&!({
                    #if flash9 var ret:Bool=untyped __global__["isNaN"](b);
                    ret;
                    #else Math.isNaN(b);
                    #end
                });
            };
            if(!res)throw "assert("+"!assert_isNaN(x)&&!assert_isNaN(a)&&!assert_isNaN(b)"+") :: "+("PR(Math).clamp2 -> "+x+" -> "+a+" -> "+b);
            #end
        };
        return if(x<a)a else if(x>b)b else x;
    }
}
